package master

import (
	"encoding/json"
	"go-crontab/common"
	"net"
	"net/http"
	"strconv"
	"time"
)

// 任务的http接口
type ApiServer struct {
	httpServer *http.Server
}

var (
	// 单例对象
	G_apiServer *ApiServer
)

// 保存任务接口
func handleJobSave(resp http.ResponseWriter, req *http.Request) {
	var (
		err    error
		jobStr string
		job    common.Job

		oldJob *common.Job
		bytes  []byte
	)
	// 解析表单中的job字段
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	// 获取表单中的job
	jobStr = req.PostForm.Get("job")
	// 反序列化job json
	if err = json.Unmarshal([]byte(jobStr), &job); err != nil {
		goto ERR
	}

	if oldJob, err = G_jobMgr.SaveJob(&job); err != nil {
		goto ERR
	}

	// 返回正常应答
	if bytes, err = common.BuildResponse(200, "success", oldJob); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
// 返回异常应答
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

// 删除任务接口
func handleJobDelete(resp http.ResponseWriter, req *http.Request) {
	var (
		err    error
		name   string
		oldJob *common.Job
		bytes  []byte
	)
	// 解析表单中的job字段
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	name = req.PostForm.Get("name")

	if oldJob, err = G_jobMgr.DeleteJob(name); err != nil {
		goto ERR
	}

	// 返回正常应答
	if bytes, err = common.BuildResponse(200, "success", oldJob); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
// 返回异常应答
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

// 任务列表接口
func handleJobList(resp http.ResponseWriter, req *http.Request) {
	var (
		err     error
		jobList []*common.Job
		bytes   []byte
	)
	if jobList, err = G_jobMgr.ListJobs(); err != nil {
		goto ERR
	}

	// 返回正常应答
	if bytes, err = common.BuildResponse(200, "success", jobList); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
// 返回异常应答
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

// 强杀某个任务接口
func handleJobKill(resp http.ResponseWriter, req *http.Request) {
	var (
		err   error
		name  string
		bytes []byte
	)
	// 解析表单中的job字段
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	name = req.PostForm.Get("name")

	if err = G_jobMgr.KillJob(name); err != nil {
		goto ERR
	}

	// 返回正常应答
	if bytes, err = common.BuildResponse(200, "success", nil); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
// 返回异常应答
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

// 任务日志查询接口
func handleJobLog(resp http.ResponseWriter, req *http.Request) {
	var (
		err       error
		name      string
		skipParm  string // 第几条开始
		limitParm string // 限制几条
		skip      int
		limit     int
		logList   []*common.JobLog
		bytes     []byte
	)
	// 解析表单中的job字段
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	name = req.Form.Get("name")
	skipParm = req.Form.Get("skip")
	limitParm = req.Form.Get("limit")
	if skip, err = strconv.Atoi(skipParm); err != nil {
		skip = 0
	}
	if limit, err = strconv.Atoi(limitParm); err != nil {
		limit = 10
	}

	if logList, err = G_logMgr.ListLog(name, skip, limit); err != nil {
		goto ERR
	}

	// 返回正常应答
	if bytes, err = common.BuildResponse(200, "success", logList); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
// 返回异常应答
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

//
func handleWorkerList(resp http.ResponseWriter, req *http.Request) {
	var (
		workerArr []string
		err error
		bytes []byte
	)

	if workerArr, err = G_workerMgr.ListWorkers(); err != nil {
		goto ERR
	}

	// 返回正常应答
	if bytes, err = common.BuildResponse(200, "success", workerArr); err == nil {
		resp.Write(bytes)
	}
	return

ERR:
// 返回异常应答
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

// 初始化http服务
func InitApiServer() (err error) {
	var (
		mux        *http.ServeMux
		listener   net.Listener
		httpServer *http.Server
		staticDir  http.Dir
		staticHand http.Handler
	)

	// option routes
	mux = http.NewServeMux()
	mux.HandleFunc("/job/save", handleJobSave)
	mux.HandleFunc("/job/delete", handleJobDelete)
	mux.HandleFunc("/job/list", handleJobList)
	mux.HandleFunc("/job/kill", handleJobKill)
	mux.HandleFunc("/job/log", handleJobLog)
	mux.HandleFunc("/worker/list", handleWorkerList)

	// 静态文件
	staticDir = http.Dir(G_config.Webroot)
	staticHand = http.FileServer(staticDir)
	mux.Handle("/", http.StripPrefix("/", staticHand))

	// TCP listening
	if listener, err = net.Listen("tcp", ":"+strconv.Itoa(G_config.ApiPort)); err != nil {
		return
	}

	httpServer = &http.Server{
		ReadTimeout:  time.Duration(G_config.ApiReadTimeout) * time.Millisecond,
		WriteTimeout: time.Duration(G_config.ApiWriteTimeout) * time.Millisecond,
		Handler:      mux,
	}

	G_apiServer = &ApiServer{
		httpServer: httpServer,
	}

	go httpServer.Serve(listener)
	return
}
